package cz.muni.fi.bugpatterndetector;

import java.util.Locale;
import org.apache.bcel.generic.BranchInstruction;
import org.apache.bcel.generic.Instruction;

import static java.lang.Integer.valueOf;

/**
 *
 * @author Michal Ďuriš
 */
public class InstructionParser {

    /**
     * Method parses jump destination from instruction
     *
     * @param instruction jump instruction
     *
     * @return jump destination on success, otherwise -2
     */
    public static int getJumpDestinationFromInstruction(Instruction instruction) {
        
        int jumpDestinationPosition = -2;

        if (instruction instanceof BranchInstruction) {
            
            BranchInstruction branchInstruction = (BranchInstruction) instruction;

            jumpDestinationPosition = branchInstruction.getTarget()
                    .getPosition();
        } else {
            
            String[] splitInstruction = instruction.toString(false).trim()
                    .split(" -> ");

            if (splitInstruction.length == 2) {
                
                jumpDestinationPosition = valueOf(splitInstruction[1]);
            }
        }
        
        return jumpDestinationPosition;
    }

    /**
     * Method parses operand from instruction
     *
     * @param instruction instruction with operand to be parsed
     *
     * @return operand id on success, otherwise -1
     */
    public static int getOperandFromInstruction(String instruction) {
        
        int operandID = -1;

        String[] splitInstruction = instruction.trim().toLowerCase(
                Locale.ENGLISH).split("\\s+");

        if (splitInstruction.length == 2) {
            
            operandID = valueOf(splitInstruction[1]);
        }

        return operandID;
    }

    /**
     * Method parses variable id from instruction
     *
     * @param instruction instruction with variable to be parsed
     * @param opcode      type of instruction
     *
     * @return variable on success, otherwise -1
     */
    public static int getVariableFromInstruction(String instruction,
                                                 String opcode) {
        
        int variableID;

        if (instruction.trim().toLowerCase(Locale.ENGLISH).startsWith(
                opcode + "_")) {
            
            variableID = valueOf(instruction.trim().toLowerCase(Locale.ENGLISH)
                    .substring(opcode.length() + 1));
            
        } else {
            
            variableID = getOperandFromInstruction(instruction);
        }

        return variableID;
    }
}
